package watch

import (
	"context"
	"github.com/go-kit/kit/log"
)

type WatchService interface {
	SearchWatchedChatroom(ctx context.Context, request searchWatchedChatroomRequest) (int64, []*WatchedChatroom, error)
	SearchWatchedMember(ctx context.Context, request searchWatchedMemberRequest) (int64, []*WatchedMember, error)
	ModifyWatchedChatroom(ctx context.Context, modifyWatchedChatroomOpt modifyWatchedChatroomRequest) error
	ModifyWatchedMember(ctx context.Context, modifyWatchedMemberOpt modifyWatchedMemberRequest) error
}

type watchService struct {
	watchRepository WatchRepository
	logger          log.Logger
}

func NewWatchService(rep WatchRepository, logger log.Logger) WatchService {
	return &watchService{
		watchRepository: rep,
		logger:          logger,
	}
}

func (ws *watchService) SearchWatchedChatroom(ctx context.Context, searchWatchedChatroomOpt searchWatchedChatroomRequest) (int64, []*WatchedChatroom, error) {
	count, chatrooms, err := ws.watchRepository.SearchWatchedChatroom(ctx, searchWatchedChatroomOpt)
	if err != nil {
		_ = ws.logger.Log("search watched fail", err)
		return 0, nil, err
	}
	var ids []string
	var idMap map[string]int64
	for _, c := range chatrooms {
		ids = append(ids, c.Id)
	}
	if len(ids) > 0 {
		idMap, err = ws.ChatroomMessageCount7(ctx, ids)
		if err != nil {
			_ = ws.logger.Log("search  chatroom 7 day message count error:", err)
			return 0, nil, err
		}
	} else {
		return count, []*WatchedChatroom{}, nil
	}

	for _, chatroom := range chatrooms {
		if count, ok := idMap[chatroom.Id]; ok {
			chatroom.MessageCount7 = count
		}
	}
	return count, chatrooms, nil
}

func (ws *watchService) SearchWatchedMember(ctx context.Context, searchWatchedMemberOpt searchWatchedMemberRequest) (int64, []*WatchedMember, error) {
	var ids []string
	var idMap map[string]int64
	count, watchMemberRes, err := ws.watchRepository.SearchWatchedMember(ctx, searchWatchedMemberOpt)
	if err != nil {
		_ = ws.logger.Log("search watched member error:", err)
		return 0, nil, err
	}
	for _, member := range watchMemberRes {
		ids = append(ids, member.Id)
	}
	if len(ids) > 0 {
		idMap, err = ws.MembersMessageCount7(ctx, ids)
		if err != nil {
			_ = ws.logger.Log("search  member 7 day message count error:", err)
			return 0, nil, err
		}
	} else {
		return count, []*WatchedMember{}, nil
	}
	for _, member := range watchMemberRes {
		if count, ok := idMap[member.Id]; ok {
			member.MessageCount7 = count
		}
	}
	return count, watchMemberRes, nil
}

func (ws *watchService) ModifyWatchedChatroom(ctx context.Context, modifyWatchedChatroomOpt modifyWatchedChatroomRequest) error {
	err := ws.watchRepository.ModifyWatchedChatroom(ctx, modifyWatchedChatroomOpt)
	return err
}

func (ws *watchService) ModifyWatchedMember(ctx context.Context, modifyWatchedMemberOpt modifyWatchedMemberRequest) error {
	err := ws.watchRepository.ModifyWatchedMember(ctx, modifyWatchedMemberOpt)
	return err
}

func (ws *watchService) MembersMessageCount7(ctx context.Context, ids []string) (map[string]int64, error) {
	idCountMap, err := ws.watchRepository.MembersMessageCount7(ctx, ids)
	if err != nil {
		_ = ws.logger.Log("search  member 7 day message count error:", err)
		return nil, err
	}
	return idCountMap, nil
}

func (ws *watchService) ChatroomMessageCount7(ctx context.Context, ids []string) (map[string]int64, error) {
	idCountMap, err := ws.watchRepository.ChatroomMessageCount7(ctx, ids)
	if err != nil {
		_ = ws.logger.Log("search  chatroom 7 day message count error:", err)
		return nil, err
	}
	return idCountMap, nil
}
